# """
# 1、单继承:
#     python面向对象的继承是指多个类之间的所属关系，即子类默认继承父类的属性和方法
#     PS:在Python中，所有类默认继承object类，object类是顶级类或者基类，其他子类叫做派生类
# """
# # 故事主线：一个煎饼果子老师傅，在煎饼果子界摸爬滚打多年，研发了一套精湛的摊煎饼果子的技术，师傅要把这套技术传授给他唯一的最得意的徒弟。
# # 分析：徒弟是不是要继承师傅的所有技术？
# # 1、师傅类
# class master():
#     def __init__(self):
#         self.kongfu = "[五香煎饼果子配方]"
#
#     def make_cake(self):
#         print(f"运用{self.kongfu}制作煎饼果子")
#
# # 2、徒弟类
# class prentice(master):
#     pass
#
# # 3、创建一个对象xiaoming
# xiaoming = prentice()
#
# # 4、对象范文实例属性
# print(xiaoming.kongfu)
#
# # 5、对象调用实例方法
# xiaoming.make_cake()
#
# # ===================================================================================
#
# """
# 2、多继承
#     所谓多继承就是一个类同时继承了多个父类
#     PS：当一个类有多个父类的时候，默认使用第一个父类的同名属性和方法
# """
# 小明是一个爱学习的好孩子，想学习更多的煎饼果子技术，于是去报了个班
# class master():
#     def __init__(self):
#         self.kongfu = "[五香煎饼果子配方]"
#
#     def make_cake(self):
#         print(f"运用{self.kongfu}制作煎饼果子")
#
# class school():
#     def __init__(self):
#         self.kongfu = "[香辣煎饼果子配方]"
#
#     def make_cake(self):
#         print(f"运用{self.kongfu}制作煎饼果子")
#
# # 2、徒弟类
# class prentice(school,master):  # 当一个类有多个父类的时候，默认使用第一个父类的同名属性和方法
#     pass
#
# # 3、创建一个对象xiaoming
# xiaoming = prentice()
#
# # 4、对象范文实例属性
# print(xiaoming.kongfu)
#
# # 5、对象调用实例方法
# xiaoming.make_cake()
#
# # ===================================================================================
#
# """
# 3、子类重写父类同名方法和属性：
#     重写的特点：
#         1、依赖于继承
#         2、重写的是父类已经有的同名的方法
#         3、重写的目的是我不想用父类的某一个方法，自己重新命名一遍
# """
#
# # 故事主线：xiaoming掌握了师傅和培训的技术后，自己潜心专研出自己的独门的配方的一套全新的煎饼果子技术
# class master():
#     def __init__(self):
#         self.kongfu = "[五香煎饼果子配方]"
#
#     def make_cake(self):
#         print(f"运用{self.kongfu}制作煎饼果子")
#
# class school():
#     def __init__(self):
#         self.kongfu = "[香辣煎饼果子配方]"
#
#     def make_cake(self):
#         print(f"运用{self.kongfu}制作煎饼果子")
#
# # 2、徒弟类
# class prentice(school,master):
#     # 开始独创煎饼果子了
#     def __init__(self):
#         self.kongfu = ["独创煎饼果子"]
#
#     def make_cake(self):
#         print(f"运用{self.kongfu}制作煎饼果子")
#
# # 3、创建一个对象xiaoming
# xiaoming = prentice()
#
# # 4、对象范文实例属性
# print(xiaoming.kongfu)
#
# # 5、对象调用实例方法
# xiaoming.make_cake()

# ===================================================================================

"""
4、子类调用父类的同名方法和属性

"""
# 故事主线：有很多顾客都希望也能吃到师傅的和学校的哪种口味的煎饼果子
class master():
    def __init__(self):
        self.kongfu = "[五香煎饼果子配方]"

    def make_cake(self):
        print(f"运用{self.kongfu}制作煎饼果子")

class school():
    def __init__(self):
        self.kongfu = "[香辣煎饼果子配方]"

    def make_cake(self):
        print(f"运用{self.kongfu}制作煎饼果子")

# 2、徒弟类
class prentice(school,master):
    # 开始独创煎饼果子了
    def __init__(self):
        # 如果有自己重写的父类方法， 最好是先将父类的初始化init给带过来
        master.__init__(self)
        school.__init__(self)
        self.kongfu = ["独创煎饼果子"]

    def make_cake(self):
        # 如果是先调用了父类的属性和方法，父类属性会覆盖子类属性，故在调用属性前，先调用自己的子类的初始化
        self.__init__()
        print(f"运用{self.kongfu}制作煎饼果子")
    # 调用父类方法，但是为保证调用到的也是父类的属性，必须在调用方法前调用父类的初始化
    def make_master_cake(self):
        master.__init__(self)
        master.make_cake(self)

    # 学校的口味也来了
    def make_school_cake(self):
        school.__init__(self)
        school.make_cake(self)

# 3、创建一个对象xiaoming
xiaoming = prentice()

# 4、对象范文实例属性
print(xiaoming.kongfu)

# 5、对象调用实例方法
xiaoming.make_cake()

# 这个调用师傅那学到的口味
xiaoming.make_master_cake()
# 这个调用学校那学到的口味
xiaoming.make_school_cake()
# 这个调用的是自己重写的父类方法，也就是自己独创的口味
xiaoming.make_cake()